package juc2.base;


/**
 * 线程状态扭转案例
 */
public class ThreadStateDemo {
    // 用于演示锁竞争的对象（共享资源）
    private static final Object lock = new Object();

    public static void main(String[] args) throws InterruptedException {
        // ====================== 主线程操作 ======================
        // 1. 主线程创建子线程对象（此时子线程处于 NEW 状态）
        Thread subThread = new Thread(() -> {
            // ====================== 子线程操作 ======================
            // 子线程进入 run() 方法，说明已被 CPU 调度（进入 RUNNING 状态）
            System.out.println("【子线程】开始执行任务（RUNNING状态）");

            try {
                // 2. 子线程调用 sleep(1000)，主动进入 TIMED_WAITING 状态
                // 此时子线程释放 CPU 资源，休眠 1 秒
                Thread.sleep(1000);
                System.out.println("【子线程】sleep结束，回到 RUNNABLE 状态");

                // 3. 子线程尝试获取 lock 锁：
                //    - 若获取成功：进入同步块
                //    - 若获取失败：进入 BLOCKED 状态（等待锁释放）
                System.out.println("【子线程】尝试获取锁（可能进入 BLOCKED 状态）");
                synchronized (lock) {
                    System.out.println("【子线程】获取锁成功，进入同步块");

                    // 4. 子线程调用 wait()，主动释放锁并进入 WAITING 状态
                    // 必须等待其他线程调用 notify() 才能唤醒
                    lock.wait();//释放锁并等待
                    System.out.println("【子线程】被唤醒，重新获取锁成功");
                }

            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            // 5. 子线程执行完 run() 方法，进入 TERMINATED 状态
            System.out.println("【子线程】任务执行结束（TERMINATED状态）");
        }, "测试子线程");

        // 主线程打印子线程初始状态（NEW）
        System.out.println("【主线程】创建子线程后，子线程状态：" + subThread.getState());

        // 主线程启动子线程（子线程进入 RUNNABLE 状态，等待 CPU 调度）
        subThread.start();

        // 主线程休眠 100ms：给子线程留出被 CPU 调度的时间
        // 此时主线程进入 TIMED_WAITING 状态，子线程有机会进入 RUNNING 状态
        Thread.sleep(100);
        System.out.println("【主线程】休眠结束，当前子线程状态：" + subThread.getState());

        // 主线程继续休眠 500ms，等待子线程进入 sleep 状态
        Thread.sleep(500);
        System.out.println("【主线程】再次休眠后，子线程状态（sleep中）：" + subThread.getState());

        // 主线程继续休眠 1000ms，等待子线程 sleep 结束并尝试获取锁
        // 此时子线程可能因未抢到锁而进入 BLOCKED 状态
        Thread.sleep(1000);
        System.out.println("【主线程】等待子线程sleep结束，子线程状态（竞争锁）：" + subThread.getState());

        // 主线程获取 lock 锁（若子线程正在等待此锁，会让子线程进入 BLOCKED 状态）
        synchronized (lock) {
            System.out.println("【主线程】获取锁成功，准备唤醒子线程");
            // 主线程调用 notify() 唤醒等待的子线程
            lock.notify();
        }

        // 主线程休眠 100ms，等待子线程被唤醒后的状态变化
        Thread.sleep(100);
        System.out.println("【主线程】唤醒子线程后，子线程状态：" + subThread.getState());

        // 主线程调用 join()，等待子线程执行完毕（主线程进入 WAITING 状态）
        subThread.join();
        System.out.println("【主线程】子线程已终止，最终状态：" + subThread.getState());
    }
}
